/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside.miscellaneous.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.IOException;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import phoside.PhosphoProteins;
import phoside.Protein;

import phoside.classify.result.PhosidePredictionResult;
import phoside.classify.result.PhosidePredictionResultImpl;

import phoside.io.ProteinsReader;
import phoside.io.xml.PhosideXmlProteinsReader;
import phoside.io.xml.PhosphoProteinFieldValueFormatter;

import phoside.util.IOUtil;
import phoside.util.ClientHttpRequest;
import phoside.util.UrlUtil;

/**
 *
 * @author gjj
 */
public class PhosphoReaderNetPhosK implements ProteinsReader {
    private PhosidePredictionResult data;
    private String dirReport;
    private String kinase;

    public PhosphoReaderNetPhosK(PhosidePredictionResult data,
            String dirReport, String kinase) {
        this.data = data;
        this.dirReport = dirReport;
        this.kinase = kinase;
    }

    public PhosphoProteins read() throws IOException {
        //List<String> lines = IOUtil.readStringListAscii(dirReport);
        FileReader fin = new FileReader(dirReport);
        BufferedReader in = new BufferedReader(fin);

        String acc = null;
        Pattern p = Pattern.compile("[STY]-([0-9]+) +([^ ]+) +([01]\\.[0-9]+)");

        String line;
        while ((line=in.readLine())!=null) {
            if (line.startsWith(">")) {
                acc = line.substring(1);
                int ix = acc.indexOf('|');
                if (ix!=-1) {
                    acc = acc.substring(0, ix);
                }

//                if (data.getProtein(acc)==null)
//                    acc = null;
            } else {
//                if (acc==null)
//                    continue;

                Matcher m = p.matcher(line);
                if (m.matches()) {
                    int site = Integer.parseInt(m.group(1))-1;
                    if (!kinase.equalsIgnoreCase(m.group(2)))
                        continue;
                    double score = Double.parseDouble(m.group(3));
                    data.setPrediction(acc, site, score);
                }
            }
        }
        return data;
    }

    public void saveResult(String dirSave) throws IOException {
        Map<String,String> resultPages = getResultPage();

        FileWriter fout = new FileWriter(dirSave);
        BufferedWriter out = new BufferedWriter(fout);

        for (Map.Entry<String,String> entry : resultPages.entrySet()) {
            String acc = entry.getKey();
            out.write(">"+acc);
            out.newLine();
            
            String page = entry.getValue();
            if (page==null) {
                System.err.println(acc);
                continue;
            }

            out.write(page);
            out.newLine();

            try {
                InputStream is = UrlUtil.getInputStream(page);
                for (String str : IOUtil.readStringListAscii(new InputStreamReader(is))) {
                    out.write(str);
                    out.newLine();
                }
                out.newLine();
            } catch (IOException e) {
                System.err.println(acc);
                e.printStackTrace();
                continue;
            }

        }

        out.close();
        fout.close();
    }

    public Map<String,String> getResultPage() {
        Map<String,String> map = new HashMap();

//        try {
//            for (String line : IOUtil.readStringListAscii("data\\phosphoelm\\netphosklink.txt")) {
//                String[] strs = line.split(" +",2);
//                if (strs[1].equals("null")) {
//                    map.put(strs[0], null);
//                } else {
//                    map.put(strs[0], strs[1]);
//                }
//            }
//        }catch (Exception e) {
//            e.printStackTrace();
//        }

        Iterator<Protein> it = data.proteinIterator();
        while (it.hasNext()) {
            Protein protein = it.next();
            java.util.List<String> lines;

            try {
                InputStream is = ClientHttpRequest.post(
                                  new java.net.URL("http://www.cbs.dtu.dk/cgi-bin/nph-webface"),
                                  new Object[] {
                                                "configfile", "/usr/opt/www/pub/CBS/services/NetPhosK-1.0/NetPhosK.cf",
                                                "seqpaste", protein.getSequence(),
                                                "method", "--no-ess",
                                                "threshold", "0.00"
                                               });

                lines = IOUtil.readStringListAscii(
                    new java.io.InputStreamReader(is));

                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
            String resultPage = null;
            for (String line:lines) {
                String stt = "If Javascript is disabled, follow <a href=\"";
                String end = "\">This link</a>";
                if (line.startsWith(stt)) {
                    int idx = line.indexOf(end);
                    resultPage = line.substring(stt.length(),idx);
                    break;
                }
            }


            System.out.println(protein.getAccession()+"\t"+resultPage);

            map.put(protein.getAccession(), resultPage);
        }
        return map;
    }

    public static void main(String[] args) {
        String testXml = "data\\phosphoelm\\Human-UniProt-SwissProt-V15.8-20090922-PhosphoELM-V8.2-April2009-nr50";
        //String testXml = "exp\\test1\\kinase-specific\\test";
        PhosidePredictionResult data = new PhosidePredictionResultImpl(null);
        PhosideXmlProteinsReader readerxml = new PhosideXmlProteinsReader(testXml+".xml", data,
                new PhosphoProteinFieldValueFormatter());

        String kinase = "CKII";
        PhosphoReaderNetPhosK reader = new PhosphoReaderNetPhosK(data,testXml+".raw.netphosk",kinase);

        phoside.io.xml.PhosideXmlProteinsWriter writer
                = new phoside.io.xml.PhosideXmlProteinsWriter(testXml+".netphosk."+kinase+".xml",
                  new phoside.io.xml.PhosphoProteinFieldValueFormatter());

        try {
            readerxml.read();
            for (String acc : data.getProteinsAccessions()) {
                data.clearSites(acc);
                data.getProtein(acc).removeInfo(phoside.util.StaticFinalValues.DISORDER);
            }

            //reader.saveResult(testXml+".raw.netphosk");

            reader.read();
            
            writer.write(data);
        } catch(IOException e) {
            e.printStackTrace();
        }

    }
}
